#pragma once

#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <string>
#include <functional>
#include <typeindex>
#include <stdexcept>
#include <type_traits>
#include <mutex>

namespace infrastructure {

/**
 * @enum Lifecycle
 * @brief 服务实例的生命周期枚举
 */
enum class Lifecycle {
    Singleton, // 单例：整个应用程序生命周期内只有一个实例
    Transient  // 瞬时：每次解析都创建一个新实例
};

/**
 * @class ServiceContainer
 * @brief 优化版本的依赖注入容器
 * @details 
 * - 使用RAII进行异常安全的栈管理
 * - 使用unordered_set优化循环依赖检测
 * - 提供更安全的类型转换
 * - 简化的工厂注册接口
 */
class ServiceContainer {
public:
    ServiceContainer() = default;
    ~ServiceContainer() = default;

    // 禁止拷贝和赋值
    ServiceContainer(const ServiceContainer&) = delete;
    ServiceContainer& operator=(const ServiceContainer&) = delete;

    /**
     * @brief 解析服务实例
     * @tparam Interface 服务接口类型
     * @return std::shared_ptr<Interface> 服务实例
     */
    template<typename Interface>
    std::shared_ptr<Interface> resolve();

    /**
     * @brief 注册服务（简单构造）
     * @tparam Interface 接口类型
     * @tparam Implementation 实现类型
     * @param lifecycle 生命周期
     */
    template<typename Interface, typename Implementation>
    void registerService(Lifecycle lifecycle = Lifecycle::Singleton);

    /**
     * @brief 注册服务（工厂函数）
     * @tparam Interface 接口类型
     * @tparam Implementation 实现类型
     * @param lifecycle 生命周期
     * @param factory 工厂函数
     */
    template<typename Interface, typename Implementation>
    void registerFactory(Lifecycle lifecycle, 
                         std::function<std::shared_ptr<Implementation>(ServiceContainer&)> factory);

    /**
     * @brief 注册单例实例
     * @tparam Interface 接口类型
     * @param instance 实例
     */
    template<typename Interface>
    void registerInstance(std::shared_ptr<Interface> instance);

private:
    /**
     * @brief RAII栈守卫，确保异常安全
     */
    class ResolutionGuard {
    public:
        ResolutionGuard(std::unordered_set<std::type_index>& set, std::type_index type);
        ~ResolutionGuard();
        
    private:
        std::unordered_set<std::type_index>& m_set;
        std::type_index m_type;
        bool m_added;
    };

    /**
     * @brief 服务工厂基类
     */
    class ServiceFactoryBase {
    public:
        virtual ~ServiceFactoryBase() = default;
    };
    
    /**
     * @brief 模板化服务工厂 - 使用直接接口指针存储
     */
    template<typename Interface, typename Implementation>
    class ServiceFactory : public ServiceFactoryBase {
    public:
        ServiceFactory(std::function<std::shared_ptr<Implementation>(ServiceContainer&)> factory)
            : m_factory(std::move(factory)) {}
        
        std::shared_ptr<Interface> createService(ServiceContainer& container) {
            // 创建实现实例
            auto impl = m_factory(container);
            // 直接返回接口指针，让编译器处理多重继承的指针调整
            return std::static_pointer_cast<Interface>(impl);
        }
        
    private:
        std::function<std::shared_ptr<Implementation>(ServiceContainer&)> m_factory;
    };

    /**
     * @brief 服务工厂信息
     */
    struct ServiceInfo {
        std::unique_ptr<ServiceFactoryBase> factory;
        Lifecycle lifecycle;
        std::type_index implementationType;
        // 添加创建函数指针，用于类型安全的对象创建
        std::function<std::shared_ptr<void>(ServiceContainer&)> createFunction;
        
        // 默认构造函数
        ServiceInfo() 
            : lifecycle(Lifecycle::Singleton)
            , implementationType(std::type_index(typeid(void))) {}
        
        // 完整构造函数
        template<typename Interface, typename Implementation>
        ServiceInfo(std::unique_ptr<ServiceFactory<Interface, Implementation>> f, 
                   Lifecycle lc, 
                   std::type_index type,
                   std::function<std::shared_ptr<Implementation>(ServiceContainer&)> factory)
            : factory(std::move(f))
            , lifecycle(lc)
            , implementationType(type) 
        {
            // 存储类型安全的创建函数
            createFunction = [factory](ServiceContainer& container) -> std::shared_ptr<void> {
                auto impl = factory(container);
                // 转换为接口类型，让编译器处理多重继承
                std::shared_ptr<Interface> interfacePtr = std::static_pointer_cast<Interface>(impl);
                return std::static_pointer_cast<void>(interfacePtr);
            };
        }
    };

    std::unordered_map<std::type_index, ServiceInfo> m_services;
    std::unordered_map<std::type_index, std::shared_ptr<void>> m_singletons;
    std::recursive_mutex m_mutex;  // 使用递归互斥锁支持工厂函数内部的resolve调用

    // 使用线程局部变量进行循环依赖检测（优化为set）
    inline static thread_local std::unordered_set<std::type_index> m_resolutionSet;
};

// 内联实现

inline ServiceContainer::ResolutionGuard::ResolutionGuard(
    std::unordered_set<std::type_index>& set, std::type_index type)
    : m_set(set), m_type(type), m_added(false)
{
    if (m_set.find(m_type) != m_set.end()) {
        throw std::runtime_error("[ServiceContainer] Circular dependency detected for: " + 
                               std::string(m_type.name()));
    }
    m_set.insert(m_type);
    m_added = true;
}

inline ServiceContainer::ResolutionGuard::~ResolutionGuard()
{
    if (m_added) {
        m_set.erase(m_type);
    }
}

template<typename Interface>
std::shared_ptr<Interface> ServiceContainer::resolve()
{
    const auto interfaceType = std::type_index(typeid(Interface));
    
    // 循环依赖检测和RAII管理
    ResolutionGuard guard(m_resolutionSet, interfaceType);
    
    std::lock_guard<std::recursive_mutex> lock(m_mutex);
    
    auto serviceIt = m_services.find(interfaceType);
    if (serviceIt == m_services.end()) {
        throw std::runtime_error("[ServiceContainer] Service not registered: " + 
                               std::string(typeid(Interface).name()));
    }
    
    const auto& serviceInfo = serviceIt->second;
    
    if (serviceInfo.lifecycle == Lifecycle::Singleton) {
        auto singletonIt = m_singletons.find(interfaceType);
        if (singletonIt != m_singletons.end()) {
            // 从缓存的单例中获取服务，直接转换为接口类型
            return std::static_pointer_cast<Interface>(singletonIt->second);
        }
        
        // 创建新的单例 - 使用类型安全的创建函数
        auto instance = serviceInfo.createFunction(*this);
        m_singletons[interfaceType] = instance;
        return std::static_pointer_cast<Interface>(instance);
    } else {
        // 瞬时实例 - 使用类型安全的创建函数
        auto instance = serviceInfo.createFunction(*this);
        return std::static_pointer_cast<Interface>(instance);
    }
}

template<typename Interface, typename Implementation>
void ServiceContainer::registerService(Lifecycle lifecycle)
{
    static_assert(std::is_base_of_v<Interface, Implementation> || 
                  std::is_same_v<Interface, Implementation>,
                  "Implementation must derive from Interface or be the same type");
    
    registerFactory<Interface, Implementation>(lifecycle, 
        [](ServiceContainer&) -> std::shared_ptr<Implementation> {
            return std::make_shared<Implementation>();
        });
}

template<typename Interface, typename Implementation>
void ServiceContainer::registerFactory(Lifecycle lifecycle,
    std::function<std::shared_ptr<Implementation>(ServiceContainer&)> factory)
{
    static_assert(std::is_base_of_v<Interface, Implementation> || 
                  std::is_same_v<Interface, Implementation>,
                  "Implementation must derive from Interface or be the same type");
    
    std::lock_guard<std::recursive_mutex> lock(m_mutex);
    
    auto serviceFactory = std::make_unique<ServiceFactory<Interface, Implementation>>(factory);
    
    ServiceInfo info;
    info.factory = std::move(serviceFactory);
    info.lifecycle = lifecycle;
    info.implementationType = std::type_index(typeid(Implementation));
    
    // 存储类型安全的创建函数
    info.createFunction = [factory](ServiceContainer& container) -> std::shared_ptr<void> {
        auto impl = factory(container);
        // 转换为接口类型，让编译器处理多重继承的指针调整
        std::shared_ptr<Interface> interfacePtr = std::static_pointer_cast<Interface>(impl);
        return std::static_pointer_cast<void>(interfacePtr);
    };
    
    m_services[std::type_index(typeid(Interface))] = std::move(info);
}

template<typename Interface>
void ServiceContainer::registerInstance(std::shared_ptr<Interface> instance)
{
    std::lock_guard<std::recursive_mutex> lock(m_mutex);
    
    auto interfaceType = std::type_index(typeid(Interface));
    
    auto serviceFactory = std::make_unique<ServiceFactory<Interface, Interface>>(
        [instance](ServiceContainer&) -> std::shared_ptr<Interface> {
            return instance;
        });
    
    ServiceInfo info;
    info.factory = std::move(serviceFactory);
    info.lifecycle = Lifecycle::Singleton;
    info.implementationType = std::type_index(typeid(Interface));
    
    // 存储类型安全的创建函数
    info.createFunction = [instance](ServiceContainer&) -> std::shared_ptr<void> {
        return std::static_pointer_cast<void>(instance);
    };
    
    m_services[interfaceType] = std::move(info);
    m_singletons[interfaceType] = std::static_pointer_cast<void>(instance);
}

} // namespace infrastructure 